package com.square.service.gateway.filter;

import com.baomidou.mybatisplus.extension.api.R;
import com.square.service.auth.consumer.feign.AuthFeign;
import com.square.service.common.consts.GlobalPrefix;
import com.square.service.common.handler.ApiCode;
import com.square.service.common.utils.SpringContextUtil;
import com.square.service.gateway.config.RoutesConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 登录认证
 * 局部过滤器
 *
 * @author : 王苏
 * @since : 2021/4/23 14:46
 */
@Slf4j
@Component
public class LoginAuthCheckGateWayFilter implements GatewayFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst(GlobalPrefix.AUTHORIZATION);
        if (StringUtils.isBlank(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.PROXY_AUTHENTICATION_REQUIRED);
            return RoutesConfig.errorInfo(exchange, R.failed(ApiCode.INVALID_PROXY));
        }
        AuthFeign authFeign = SpringContextUtil.getApplicationContext().getBean(AuthFeign.class);
        R<?> r = authFeign.doGetAuthenticationInfo(token);
        if (!r.ok()) {
            log.debug(r.getMsg());
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return RoutesConfig.errorInfo(exchange, r);
        }
        ServerHttpRequest mutableReq = exchange.getRequest().mutate().header(GlobalPrefix.AUTHORIZATION_USERKEY, r.getData().toString()).build();
        ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
        return chain.filter(mutableExchange);
    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }

}
